import { reactive } from 'vue'

import { Buffer } from 'buffer'
import { useCookies } from 'vue3-cookies'

import erc20Info from './erc20.json'

import http from '@/http'
// import WalletConnectProvider from "@walletconnect/web3-provider";
import WalletConnect from '@walletconnect/client'
import QRCodeModal from '@walletconnect/qrcode-modal'

const ERC20 = erc20Info.abi
window.Buffer = Buffer

var abi = [
  {
    anonymous: false,
    inputs: [
      {
        indexed: true,
        internalType: 'address',
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        internalType: 'address',
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        internalType: 'uint256',
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  },
  {
    anonymous: false,
    inputs: [
      {
        indexed: true,
        internalType: 'address',
        name: 'from',
        type: 'address',
      },
      {
        indexed: true,
        internalType: 'address',
        name: 'to',
        type: 'address',
      },
      {
        indexed: false,
        internalType: 'uint256',
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    constant: false,
    inputs: [
      {
        internalType: 'address',
        name: 'spender',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'approve',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    constant: false,
    inputs: [
      {
        internalType: 'address',
        name: 'spender',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'subtractedValue',
        type: 'uint256',
      },
    ],
    name: 'decreaseAllowance',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    constant: false,
    inputs: [
      {
        internalType: 'address',
        name: 'spender',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'addedValue',
        type: 'uint256',
      },
    ],
    name: 'increaseAllowance',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    constant: false,
    inputs: [
      {
        internalType: 'address',
        name: 'recipient',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'amount',
        type: 'uint256',
      },
    ],
    name: 'transfer',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    constant: false,
    inputs: [
      {
        internalType: 'address',
        name: 'sender',
        type: 'address',
      },
      {
        internalType: 'address',
        name: 'recipient',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: 'amount',
        type: 'uint256',
      },
    ],
    name: 'transferFrom',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    payable: false,
    stateMutability: 'nonpayable',
    type: 'constructor',
  },
  {
    constant: true,
    inputs: [
      {
        internalType: 'address',
        name: 'owner',
        type: 'address',
      },
      {
        internalType: 'address',
        name: 'spender',
        type: 'address',
      },
    ],
    name: 'allowance',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
  {
    constant: true,
    inputs: [
      {
        internalType: 'address',
        name: 'account',
        type: 'address',
      },
    ],
    name: 'balanceOf',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
  {
    constant: true,
    inputs: [],
    name: 'decimals',
    outputs: [
      {
        internalType: 'uint8',
        name: '',
        type: 'uint8',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
  {
    constant: true,
    inputs: [],
    name: 'name',
    outputs: [
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
  {
    constant: true,
    inputs: [],
    name: 'symbol',
    outputs: [
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
  {
    constant: true,
    inputs: [],
    name: 'totalSupply',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    payable: false,
    stateMutability: 'view',
    type: 'function',
  },
]

var idoAbi = [
  {
    anonymous: false,
    inputs: [
      {
        indexed: true,
        internalType: 'address',
        name: 'previousOwner',
        type: 'address',
      },
      {
        indexed: true,
        internalType: 'address',
        name: 'newOwner',
        type: 'address',
      },
    ],
    name: 'OwnershipTransferred',
    type: 'event',
  },
  {
    inputs: [],
    name: 'DAOAddress',
    outputs: [
      {
        internalType: 'address',
        name: '',
        type: 'address',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'UAddress',
    outputs: [
      {
        internalType: 'address',
        name: '',
        type: 'address',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'uint256',
        name: 'paymentAmount_',
        type: 'uint256',
      },
    ],
    name: 'calculateSaleQuote',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'decimals',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: '_DAOAddress',
        type: 'address',
      },
      {
        internalType: 'address',
        name: '_tokenAddress',
        type: 'address',
      },
      {
        internalType: 'address',
        name: '_UAddress',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: '_minAmount',
        type: 'uint256',
      },
      {
        internalType: 'uint256',
        name: '_maxAmount',
        type: 'uint256',
      },
      {
        internalType: 'uint256',
        name: '_toTalAmount',
        type: 'uint256',
      },
      {
        internalType: 'uint256',
        name: '_salePrice',
        type: 'uint256',
      },
      {
        internalType: 'uint256',
        name: '_decimals',
        type: 'uint256',
      },
    ],
    name: 'initialize',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    name: 'maxAmount',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'minAmount',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'owner',
    outputs: [
      {
        internalType: 'address',
        name: '',
        type: 'address',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'uint256',
        name: '_val',
        type: 'uint256',
      },
    ],
    name: 'purchaseaToken',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    name: 'renounceOwnership',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    name: 'salePrice',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'saleStarted',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'sellAmount',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'setStart',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    name: 'toTalAmount',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: 'tokenAddress',
    outputs: [
      {
        internalType: 'address',
        name: '',
        type: 'address',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: 'newOwner_',
        type: 'address',
      },
    ],
    name: 'transferOwnership',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: '_token',
        type: 'address',
      },
      {
        internalType: 'uint256',
        name: '_amount',
        type: 'uint256',
      },
    ],
    name: 'withdraw',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
]

const chainId = '0x38'
// const chainId = '0x61'

var web3 = {}

// if (__DAPP__) {
web3 = new Web3(
  // "http://127.0.0.1:8545" // 本地
  // "https://nodes.pancakeswap.com/" // 362 自己的节点
  chainId === '0x38'
    ? 'https://bsc-dataseed1.ninicoin.io'
    : 'https://data-seed-prebsc-1-s2.binance.org:8545/',
)
// }

var address = ''

let initWalletLoading = false

const state = reactive({
  isInitialized: false, // 是否初始化钱包状态
  active: false,
  loaded: false,
  address: '',
  lang: '',
  connected: false,
  connectType: '', // metamask|connect|http
  token: '', // 账号登录才有用
})

const { cookies } = useCookies()

// if (!__DAPP__) {
//     var _token = cookies.get('token3')
//     if (_token && _token.length === 32) {
//         state.token = _token
//         state.connectType = 'http'
//         state.connected = true
//     }
// }

const listeners = []

function addConnectListener(listner) {
  listeners.push(listner)
}

const addNetwork = (params) =>
  window.ethereum
    .request({ method: 'wallet_addEthereumChain', params })
    .then(() => {
      // setLog([...log, `Switched to ${params[0].chainName} (${parseInt(params[0].chainId)})`])
      // setChainId(parseInt(params[0].chainId))
      console.log('set ok ?')
    })
    .catch((error) => console.error(`Error: ${error.message}`))

const bridge = 'https://bridge.walletconnect.org'
// const bridge = "http://192.168.2.188:7000";
// create new connector
let connector = {
  on: () => {},
  killSession: () => {},
}

// if (__DAPP__) {
connector = new WalletConnect({
  bridge,
  qrcodeModal: QRCodeModal,
  qrcodeModalOptions: {
    mobileLinks: [
      'argent',
      'imtoken',
      'trust',
      'metamask',
      'tokenpocket',
      'bitpie',
      'math',
      'safepal',
      'pillar',
      // 'equalwallet',
      // 'coolwallet',
      // 'xwallet',
      // 'atomic',
      // 'cosmostation',
      // 'infinity',
      'coin98',
      'bitkeep',
      'bitpay',
    ],
  },
})

connector.on('connect', (error, payload) => {
  if (error) {
    throw error
  }

  // Get provided accounts and chainId
  const { accounts, chainId } = payload.params[0]

  // alert(chainId + '-' + JSON.stringify(accounts))
  state.address = accounts[0]
  state.connected = true
  state.connectType = 'connect'
  listeners.map((fn) => fn())

  // console.log('connect==', accounts, chainId);
})

connector.on('disconnect', (error, payload) => {
  console.log('disconnect')
  state.address = ''
  state.active = false
  state.connected = false
})

// }

async function disconnect() {
  console.log('disconnect..')
  state.connected = false
  state.address = ''
  state.token = ''
  cookies.remove('token3')
  connector.killSession()
}

async function connectMetamask() {
  let _chainId = await ethereum.request({ method: 'eth_chainId' })
  console.log('chainId=', _chainId)
  if (_chainId !== chainId) {
    console.log('切换chainId')
    if (chainId === '0x38') {
      await addNetwork([
        {
          chainId: '0x38',
          chainName: 'Binance Smart Chain',
          nativeCurrency: {
            name: 'BNB',
            symbol: 'BNB',
            decimals: 18,
          },
          rpcUrls: ['https://bsc-dataseed1.ninicoin.io'],
          blockExplorerUrls: ['https://bscscan.com/'],
        },
      ])
    } else if (chainId === '0x61') {
      await addNetwork([
        {
          chainId: '0x61',
          chainName: 'Binance Smart Test Chain',
          nativeCurrency: {
            name: 'tBNB',
            symbol: 'tBNB',
            decimals: 18,
          },
          rpcUrls: ['https://data-seed-prebsc-1-s2.binance.org:8545/'],
          blockExplorerUrls: ['https://testnet.bscscan.com/'],
        },
      ])
    }

    _chainId = await ethereum.request({ method: 'eth_chainId' })
    console.log('chainId2=', _chainId)
    if (_chainId !== chainId) {
      throw Error('切换节点失败')
    }
  }
  ethereum.on('networkChanged', () => {
    location.reload()
  })
  ethereum.on('accountsChanged', () => {
    location.reload()
  })
  console.log('eth_requestAccounts==')
  const accounts = await ethereum.request({ method: 'eth_requestAccounts' })
  // address = ethereum.selectedAddress
  console.log('aa=', accounts, ethereum.selectedAddress)
  if (accounts) {
    state.address = accounts[0]
    // state.address = ''  // test
    state.connected = true
    state.connectType = 'metamask'
    listeners.map((fn) => fn())
  }
  return address
}

function isMetamask() {
  return (
    !window.Bitpie &&
    typeof window.ethereum !== 'undefined' &&
    window.ethereum.isMetaMask
  )
  // return __DEBUG__ && typeof window.ethereum !== 'undefined' && window.ethereum.isMetaMask
}

async function connect(create) {
  // 24b861d722036a724d8918051be848ab
  // if (!__DAPP__) {
  //     return
  // }

  if (isMetamask()) {
    await connectMetamask()
    return
  }

  window.connector = connector
  if (!connector.connected) {
    // console.log('connection not found=', create)
    // console.log(connector);
    if (create) {
      // if (connector.session) {
      //     console.log('kill=');
      //     //await connector.killSession()
      // }
      // console.log('create');
      await connector.createSession({ chainId: 0x38 })
    }
  } else {
    const { connected, accounts, peerMeta } = connector
    console.log('connected cache=', connected, accounts, peerMeta)
    // connector.killSession()
    if (accounts) {
      state.address = accounts[0]
      state.connected = true
      state.connectType = 'connect'
      listeners.map((fn) => fn())
    } else {
      // connector.killSession()
      // connector.connected = false
    }
  }
}

async function getAddress() {
  return state.address
}

async function sign() {
  if (state.connectType === 'http') {
    return '&token=' + state.token
  }

  const msg = 'time' + Math.floor(Date.now() / 1000)
  var address = state.address

  if (state.connectType === 'metamask') {
    let method = 'eth_sign'
    let data
    if (window.bitkeep) {
      data = msg
    } else if (window.Bitpie) {
      method = 'personal_sign'
      // data = msg
      // data = 'login'
      data = web3.utils.keccak256(
        '\x19Ethereum Signed Message:\n' + msg.length + msg,
      )
    } else {
      data = web3.utils.keccak256(
        '\x19Ethereum Signed Message:\n' + msg.length + msg,
      )
    }
    var s
    try {
      console.log('request=', method, address, data)
      s = await ethereum.request({ method: method, params: [address, data] })
      console.log(s)
      // s = await ethereum.request({ method: 'personal_sign', params: [ethereum.selectedAddress, 'login'] }).then(function(res){console.log('sign=',res)});
    } catch (e) {
      throw Error('sign error')
    }
    let params = `&address=${state.address}&msg=${msg}&sign=${s}`
    return params
  } else if (state.connectType === 'connect') {
    console.log('request sign msg', address, msg)
    const s = await connector.signMessage([address, msg])
    console.log('sign result==', s)
    return `&address=${state.address}&msg=${msg}&sign=${s}`
  } else if (state.connectType === 'http') {
    return ''
  } else {
    throw Error('no connect wallet')
  }
}

async function transfer(contractAddress, toAddr, amount, decimal) {
  // var wei = '0x' + (amount*(10**decimal)).toString(16)
  var ww = { 18: 'ether', 6: 'mwei', 9: 'gwei' }[decimal]
  var wei = web3.utils.toWei(amount, ww)
  console.log('transfer', contractAddress, toAddr, amount, decimal, wei)
  var balance
  if (
    contractAddress === '' ||
    contractAddress === '0x0000000000000000000000000000000000000000'
  ) {
    var bb = await web3.eth.getBalance(await getAddress())
    balance = web3.utils.fromWei(bb, ww)
    console.log('balance=', balance)
    if (amount * 1 > balance) {
      // if (amount > balance) {
      Toast('Insufficient Amount')
      throw Error('Insufficient Amount')
    }
    var hexValue = '0x' + (wei * 1).toString(16)
    return request(null, toAddr, hexValue)
  } else {
    balance = await balanceOf(contractAddress, await getAddress(), decimal)
    console.log('balance=', balance)
    if (amount * 1 > balance) {
      // if (amount > balance) {
      Toast('Insufficient Amount')
      throw Error('Insufficient Amount')
    }
    const contract = new web3.eth.Contract(abi, contractAddress)
    var fn = contract.methods.transfer(toAddr, wei)
    return request(fn, contractAddress)
  }
}

async function idoBuy(contractAddress, fromContractAddress, amount) {
  const isOpen = await idoBegin(contractAddress)
  if (!isOpen) {
    Toast('募集活动未开始')
    return ''
  }
  const min = await idoMin(contractAddress)
  if (amount * 1 < min) {
    Toast('单笔最小认购数量为' + min + 'USDT')
    return ''
  }
  const max = await idoMax(contractAddress)
  if (amount * 1 > max) {
    Toast('单笔最大认购数量为' + max + 'USDT')
    return ''
  }
  var address = await getAddress()
  const balance = await balanceOf(fromContractAddress, address, 18)
  if (amount * 1 > balance) {
    Toast('余额不足')
    return ''
  }
  const wei = web3.utils.toWei(amount + '', 'ether')
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  var fn = idoContract.methods.purchaseaToken(wei)
  var tx = await request(fn, contractAddress)
  console.log(tx)
  return tx
}
async function setStart(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  var fn = idoContract.methods.setStart()
  var tx = await request(fn, contractAddress)
  return tx
}
async function idoChange(
  contractAddress,
  DAOAddress,
  tokenAddress,
  UAddress,
  minAmount,
  maxAmount,
  toTalAmount,
  price,
  decimals,
) {
  console.log(minAmount, maxAmount, toTalAmount, price, decimals)
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  var fn = idoContract.methods.initialize(
    DAOAddress,
    tokenAddress,
    UAddress,
    web3.utils.toWei(minAmount + '', 'ether'),
    web3.utils.toWei(maxAmount + '', 'ether'),
    web3.utils.toWei(toTalAmount + '', 'ether'),
    web3.utils.toWei(price + '', 'ether'),
    decimals,
  )
  var tx = await request(fn, contractAddress)
  return tx
}

async function idoApprove(contractAddress, fromContractAddress, amount) {
  const wei = web3.utils.toWei(amount + '', 'ether')
  const usdtContract = new web3.eth.Contract(ERC20, fromContractAddress)
  const approveFn = await usdtContract.methods.approve(contractAddress, wei)
  var approveTx = await request(approveFn, fromContractAddress)
  console.log('approveTx', approveTx)
  return approveTx
}

async function getAllowance(contractAddress, fromContractAddress) {
  const usdtContract = new web3.eth.Contract(ERC20, fromContractAddress)
  const allowance = await usdtContract.methods
    .allowance(await getAddress(), contractAddress)
    .call()
  return web3.utils.fromWei(allowance + '', 'ether')
}

async function getIdoPrice(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  const price = await idoContract.methods.salePrice().call()
  return web3.utils.fromWei(price + '', 'ether')
}
async function geIdoTotalAmount(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  const totalAmount = await idoContract.methods.toTalAmount().call()
  return web3.utils.fromWei(totalAmount + '', 'ether')
}
async function geIdoDaoAddress(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  return await idoContract.methods.DAOAddress().call()
}
async function geIdoTokenAddress(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  return await idoContract.methods.tokenAddress().call()
}
async function geIdoUAddress(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  return await idoContract.methods.UAddress().call()
}
async function getIdoDecimals(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  return await idoContract.methods.decimals().call()
}
async function idoMin(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  const min = await idoContract.methods.minAmount().call()
  return web3.utils.fromWei(min + '', 'ether')
}
async function idoMax(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  const max = await idoContract.methods.maxAmount().call()
  return web3.utils.fromWei(max + '', 'ether')
}
async function idoBegin(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  return await idoContract.methods.saleStarted().call()
}
async function idoHadAmount(contractAddress) {
  const idoContract = new web3.eth.Contract(idoAbi, contractAddress)
  const price = await idoContract.methods.sellAmount().call()
  return web3.utils.fromWei(price + '', 'ether')
}

async function balanceOf(contractAddress, address, decimal) {
  const contract = new web3.eth.Contract(abi, contractAddress)
  var balance = await contract.methods.balanceOf(address).call()
  console.log('balanceOf=', contractAddress, address, decimal, balance)
  balance = (balance / 10 ** decimal).toFixed(2)
  return balance
}

async function request(fn, contractAddress, value='0x00') {
  var data = '0x'
  var fromAddr = await getAddress()
  var gas = '0x5208'
  if (fn) {
    data = fn.encodeABI()
    gas = await fn.estimateGas({
      from: fromAddr,
    })
  }

  const transactionParameters = {
    // nonce: '0x00', // ignored by MetaMask
    // gasPrice: '0x09184e72a000', // customizable by user during MetaMask confirmation.
    // gas: '0x2710', // customizable by user during MetaMask confirmation.
    gas: `${gas}`,
    to: contractAddress, // Required except during contract publications.
    from: fromAddr, // must match user's active address.
    value: value, // Only required to send ether to the recipient from the initiating external account.
    data: data, // Optional, but used for defining smart contract creation and interaction.
    // chainId: '128', // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.
  }
  console.log('transactionParameters', transactionParameters)

  var txHash

  if (state.connectType === 'metamask') {
    txHash = await ethereum.request({
      method: 'eth_sendTransaction',
      params: [transactionParameters],
    })
    return txHash
  } else if (state.connectType === 'connect') {
    txHash = await connector.sendTransaction({
      gas: `${gas}`,
      to: contractAddress, // Required except during contract publications.
      from: fromAddr, // must match user's active address.
      value: '0x00', // Only required to send ether to the recipient from the initiating external account.
      data: data,
      chainId: 0x38,
    })
  }

  console.log('submit txHash=', txHash)

  return txHash
}

async function watch(txid) {
  return new Promise((resolve) => {
    var timer = setInterval(async () => {
      var tx = await web3.eth.getTransaction(txid)
      console.log('tx===', tx)
      if (tx && tx.blockNumber > 0) {
        clearInterval(timer)
        resolve(true)
      }
    }, 2000)
  })
}

// 初始化钱包状态
// @param changeUrl 更新 url，以便登录成功后从指定页面刷新
async function initWalletStatus(changeUrl, fail) {
  // 是否需要跳转到激活页面
  let needToTrade = false
  if (state.isInitialized) return { needToTrade }

  // 初始请求是否loading中
  if (initWalletLoading) return { initWalletLoading }

  return new Promise(function (resolve, reject) {
    changeUrl()
    initWalletLoading = true
    addConnectListener(() => {
      return http
        .get(`/api/user/isActive`)
        .then((res) => {
          if (res.code === 200) {
            state.active = res.data

            state.loaded = true

            state.isInitialized = true
          }
          if (!state.active) {
            needToTrade = true
          }
          resolve({ needToTrade })
        })
        .finally(() => {
          initWalletLoading = false
        })
        .catch((e) => {
          fail(e)
          reject(e)
        })
    })
    connect(false)
      .finally(() => {
        initWalletLoading = false
      })
      .catch((e) => {
        fail(e)
        reject(e)
      })
  })
}

export {
  state,
  getAddress,
  transfer,
  sign,
  connect,
  disconnect,
  addConnectListener,
  balanceOf,
  idoBegin,
  idoMax,
  idoMin,
  idoBuy,
  idoApprove,
  getAllowance,
  idoHadAmount,
  getIdoPrice,
  watch,
  setStart,
  geIdoTotalAmount,
  geIdoDaoAddress,
  geIdoTokenAddress,
  geIdoUAddress,
  getIdoDecimals,
  idoChange,
  initWalletStatus,
}
